package com.rgbgame.game;

import processing.core.PApplet;
import com.rgbgame.util.Util;

final class Box2d {
        public Vector3d minVec;
        public Vector3d maxVec;

        public Box2d(Vector3d _min, Vector3d _max) {
            // debugCounter++;
            minVec = new Vector3d(_min.x, _min.y, 0);
            maxVec = new Vector3d(_max.x, _max.y, 0);
            if (minVec.x > maxVec.x) {
                minVec.x = maxVec.x;
                maxVec.x = _min.x;
            }
            if (minVec.y > maxVec.y) {
                minVec.y = maxVec.y;
                maxVec.y = _min.y;
            }
        }

        public Box2d(float x1, float y1, float x2, float y2) {
            // debugCounter++;
            minVec = new Vector3d(x1, y1, 0);
            maxVec = new Vector3d(x2, y2, 0);
            if (minVec.x > maxVec.x) {
                minVec.x = maxVec.x;
                maxVec.x = x1;
            }
            if (minVec.y > maxVec.y) {
                minVec.y = maxVec.y;
                maxVec.y = y1;
            }
        }

        public void set(float x1, float y1, float x2, float y2) {
            minVec.set(x1, y1, 0);
            maxVec.set(x2, y2, 0);
            if (minVec.x > maxVec.x) {
                minVec.x = maxVec.x;
                maxVec.x = x1;
            }
            if (minVec.y > maxVec.y) {
                minVec.y = maxVec.y;
                maxVec.y = y1;
            }
        }

        public void expand(float amt) {
            // Push out all edges by amt - useful for catching edge cases
            minVec.x -= amt;
            minVec.y -= amt;
            maxVec.x += amt;
            maxVec.y += amt;
        }

        public boolean contains(Vector3d test) {
            // Does it contain the point "test"?
            if (test.x > minVec.x && test.x < maxVec.x && test.y > minVec.y
                    && test.y < maxVec.y) {
                return true;
            } else {
                return false;
            }
        }

        public boolean hitBy(Vector3d lineA, Vector3d lineB) {
            // Is it pierced by the line segment between lineA and lineB?
            // First some early exit stuff
            if (lineA.x > maxVec.x && lineB.x > maxVec.x) {
                return false;
            }
            if (lineA.x < minVec.x && lineB.x < minVec.x) {
                return false;
            }
            if (lineA.y > maxVec.y && lineB.y > maxVec.y) {
                return false;
            }
            if (lineA.y < minVec.y && lineB.y < minVec.y) {
                return false;
            }
            if (contains(lineA) || contains(lineB)) {
                return true;
            } // quick test
            else if (Util.lineCross(lineA, lineB, minVec, maxVec)
                    || Util.lineCross(lineA, lineB, new Vector3d(minVec.x - PApplet.EPSILON,
                    maxVec.y + PApplet.EPSILON, 0), new Vector3d(maxVec.x
                    + PApplet.EPSILON, minVec.y - PApplet.EPSILON, 0))) {
                return true;
            } // detailed test
            else {
                return false;
            } // no pierce
        }

        public void draw() {
            rgbGame.pApplet.stroke(255);
            rgbGame.pApplet.rect(minVec.x, minVec.y, (maxVec.x - minVec.x),
                    (maxVec.y - minVec.y));
        }

    }
